home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / FBSpriteWorld 1.05b / Project 1.01b / FBSpriteWorld.incl < prev    next >
Encoding:
Text File  |  1994-04-26  |  34.7 KB  |  1,003 lines  |  [TEXT/ZBAS]

  1. 'FBSpriteWorld.incl by Robert Hommel
  2. '© Copyright 1994
  3. 'All rights granted for any use whatsoever
  4.  
  5. 'version 1.01b
  6.  
  7. 'Disclaimer:  I've tested these routines quite thoroughly on my Mac
  8. 'LC running System 7.01 and FB 1.02c.  I make no promises or warranties 
  9. 'of any kind.
  10. '*********************************************************************
  11.  
  12. COMPILE 0, _MacsBugLabels _caseInsensitive _STRResource
  13. INCLUDE FILE _aplIncl
  14. DEFSTR LONG
  15. DEFINT A-Z
  16.  
  17. '--------------------------- GLOBALS ---------------------------------
  18.  
  19. GLOBALS "GraphicUtils.glbl"
  20. GLOBALS "FBSpriteWorld.glbl"
  21.  
  22. END GLOBALS
  23.  
  24. '------------------------- INCLUDE FILES -----------------------------
  25.  
  26. INCLUDE "TimeManager.incl"
  27. INCLUDE "GraphicUtils.incl"
  28.  
  29. '--------------------------- FUNCTIONS -------------------------------
  30.  
  31. '---------------------------------------------------------------------
  32. 'SWEnterSpriteWorld
  33. '---------------------------------------------------------------------
  34.  
  35. CLEAR LOCAL
  36. LOCAL FN SWEnterSpriteWorld
  37.   'Make sure we can run in this environment & set globals.
  38.   
  39.   gColorDepth=SYSTEM(_maxColors)
  40.   LONG IF SYSTEM(_sysVers)>700
  41.     tmp=FN GESTALT(_gestaltTimeMgrVersion)
  42.     IF tmp<_gestaltStandardTimeMgr THEN tmp=_swTimeMgrNotPresent ELSE tmp=_noErr
  43.   XELSE
  44.     tmp=_swNotSystemSeven
  45.   END IF
  46. END FN=tmp
  47.  
  48. '---------------------------------------------------------------------
  49. 'SWGetBestPort
  50. '---------------------------------------------------------------------
  51.  
  52. CLEAR LOCAL
  53. LOCAL FN SWGetBestPort&(rectPtr&)
  54.   'Returns a pointer to a grafport based on the current screen depth.
  55.   
  56.   LONG IF gColorDepth = 32                        '32-bit QuickDraw available?
  57.     offPort& = FN GetOffScrnGWorld&(rectPtr&)     'get color gWorld the size of pict rect
  58.   XELSE
  59.     offPort& = FN GetOffScrnPort&(rectPtr&)       'get B&W port the size of pict rect
  60.   END IF
  61. END FN=offPort&
  62.  
  63. '---------------------------------------------------------------------
  64. 'SWInitSpriteWorld
  65. '---------------------------------------------------------------------
  66.  
  67. CLEAR LOCAL
  68. LOCAL FN SWCreateSpriteWorld(spriteWorldPtr&,srcPort&,rectPtr&,pictHdl&)
  69.   'Given a valid SpriteWorld pointer, this function creates all 
  70.   'associated frames and sets the boundsRect.  Returns appropriate
  71.   'error code.
  72.   
  73.   err=0                                           'initialize function return var
  74.   
  75.   'set boundsRect
  76.   BLOCKMOVE rectPtr&,spriteWorldPtr&+_boundsRect,8
  77.   
  78.   'set windowFrame
  79.   spriteWorldPtr&.windowFramePtr&=srcPort&
  80.   
  81.   'create backFrame
  82.   offPort&=FN SWGetBestPort&(rectPtr&)
  83.   LONG IF offPort&
  84.     spriteWorldPtr&.backFramePtr&=offPort&
  85.     'create loadFrame
  86.     offPort&=FN SWGetBestPort&(rectPtr&)
  87.     LONG IF offPort&
  88.       spriteWorldPtr&.loadFramePtr&=offPort&
  89.       'set backPict
  90.       spriteWorldPtr&.backpictHdl&=pictHdl&
  91.     XELSE
  92.       err=_swOutOfMemory
  93.     END IF
  94.   XELSE
  95.     err=_swOutOfMemory
  96.   END IF
  97. END FN=err
  98.  
  99. '---------------------------------------------------------------------
  100. 'SWCreateSWFromWindow
  101. '---------------------------------------------------------------------
  102.  
  103. CLEAR LOCAL
  104. LOCAL FN SWCreateSWFromWindow(spriteWorldPtr&,srcPort&)
  105.   'Creates all associated frames and boundsRect based on a window's
  106.   'grafPort.  Returns appropriate error code.
  107.   
  108.   savePort&=FN GetCurrPort                        'save current port
  109.   FN SetThePort(srcPort&)                         'set port to target window
  110.   
  111.   LONG IF spriteWorldPtr&=_nil                    'did we get it?
  112.     err=_swOutOfMemory                            'couldn't allocate pointer
  113.   XELSE                                           'got it!
  114.     pictHdl&=USR GETPICT(#srcPort&+_portRect)     'take snapshot of background
  115.     'initialize the new SpriteWorld based on the window
  116.     err=FN SWCreateSpriteWorld(spriteWorldPtr&,srcPort&,srcPort&+_portRect,pictHdl&)
  117.   END IF
  118.   
  119.   FN SetThePort(savePort&)                        'reset port
  120. END FN=err
  121.  
  122. '---------------------------------------------------------------------
  123. 'SWDisposFrame
  124. '---------------------------------------------------------------------
  125.  
  126. CLEAR LOCAL
  127. LOCAL FN SWDisposFrame(framePtr&)
  128.   'Releases memory occupied by framePtr&. Returns osErr.
  129.   
  130.   osErr=FN DisposeGrafPort(framePtr&.imageMapPtr&)
  131.   IF osErr=_noErr THEN osErr=FN DisposeGrafPort(framePtr&.maskMapPtr&)
  132. END FN=osErr
  133.  
  134. '---------------------------------------------------------------------
  135. 'SWDisposSprite
  136. '---------------------------------------------------------------------
  137.  
  138. CLEAR LOCAL
  139. LOCAL FN SWDisposSprite(spritePtr&,removeFrames)
  140.   'Disposes of mask region, removes time and frame tasks, and (optionally)
  141.   'removes all frames associated with spritePtr&.
  142.   
  143.   'dispose mask region
  144.   CALL DISPOSERGN(spritePtr&.maskRegionHdl&)
  145.   'remove time tasks
  146.   FN RmvTime(spritePtr&+_frameTimeTask&)
  147.   FN RmvTime(spritePtr&+_moveTimeTask&)
  148.   'if removeFrames=_zTrue, remove all frames contained in this Sprite
  149.   LONG IF removeFrames
  150.     FOR frame=0 TO spritePtr&.totalFrames%-1
  151.       framePtr&=[spritePtr&+_frameList+(frame*4)]
  152.       osErr=FN SWDisposFrame(framePtr&)
  153.       IF osErr<>_noErr THEN EXIT FN
  154.     NEXT
  155.   END IF
  156. END FN=osErr
  157.  
  158. '---------------------------------------------------------------------
  159. 'SWDisposSpriteWorld
  160. '---------------------------------------------------------------------
  161.  
  162. CLEAR LOCAL
  163. LOCAL FN SWDisposSpriteWorld(SWPtr&)
  164.   'Releases memory occupied by SpriteWorld Frames and disposes of any
  165.   'sprites contained by SWPtr&.
  166.   
  167.   'delete backFrame and loadFrame...
  168.   osErr=FN DisposeGrafPort(SWPtr&.backFramePtr&)
  169.   LONG IF osErr=_noErr
  170.     osErr=FN DisposeGrafPort(SWPtr&.loadFramePtr&)
  171.     LONG IF osErr=_noErr
  172.       'delete all image and mask frames...
  173.       FOR layer=0 TO SWPtr&.totalLayers%-1
  174.         layerPtr&=[SWPtr&+_layerList+(layer*4)]
  175.         FOR sprite=0 TO {layerPtr&+_totalSprites}-1
  176.           spritePtr&=[layerPtr&+_spriteList+(sprite*4)]
  177.           'dispose sprite and remove frames if not cloned…
  178.           removeFrames=NOT(spritePtr&.isClone%)
  179.           osErr=FN SWDisposSprite(spritePtr&,removeFrames)
  180.           IF osErr<>_noErr THEN EXIT FN
  181.         NEXT
  182.       NEXT
  183.       KILL PICTURE SWPtr&.backPictHdl&
  184.     END IF
  185.   END IF
  186. END FN=osErr
  187.  
  188. '---------------------------------------------------------------------
  189. 'SWUpdateSpriteWorld
  190. '---------------------------------------------------------------------
  191.  
  192. CLEAR LOCAL
  193. LOCAL FN SWRefreshBackground(SWPtr&)
  194.   'Copies backPict to backFrame and refreshes loadframe.
  195.   
  196.   DIM tempRect.8
  197.   tempRect;8=SWPtr&+_boundsRect
  198.   
  199.   savePort&=FN GetCurrPort                        'save current port
  200.   FN SetThePort (SWPtr&.backFramePtr&)            'set output to backFrame
  201.   CALL DRAWPICTURE(SWPtr&.backPictHdl&,tempRect)  'draw picture to backFrame
  202.   'refresh loadFrame with background
  203.   FN SetThePort(SWPtr&.loadFramePtr&)             'set port to loadFrame
  204.   FN CopyOffScreenBits(SWPtr&.backFramePtr&,SWPtr&.loadFramePtr&,@tempRect,@tempRect,_srcCopy,0)
  205.   FN SetThePort(savePort&)                        'restore port
  206. END FN
  207.  
  208. '---------------------------------------------------------------------
  209. 'SWSetBackgroundPict
  210. '---------------------------------------------------------------------
  211.  
  212. CLEAR LOCAL
  213. LOCAL FN SWSetBackgroundPict(SWPtr&,pictHdl&)
  214.   'Sets the background PICT to pictHdl&.  This background will not
  215.   'appear on the screen until you call SWRefreshBackground.
  216.   
  217.   SWPtr&.backPictHdl&=pictHdl&
  218. END FN
  219.  
  220. '---------------------------------------------------------------------
  221. 'SWProcessSpriteWorld
  222. '---------------------------------------------------------------------
  223.  
  224. CLEAR LOCAL
  225. LOCAL FN SWProcessSpriteWorld(SWPtr&)
  226.   'Sets current rect and frame for each sprite
  227.   
  228.   FOR layer=0 TO SWPtr&.totalLayers%-1
  229.     layerPtr&=[SWPtr&+_layerList+(layer*4)]
  230.     FOR sprite=0 TO layerPtr&.totalSprites%-1
  231.       'set current frame...
  232.       spritePtr&=[layerPtr&+_spriteList+(sprite*4)]
  233.       LONG IF spritePtr&.frameTTHasFired%
  234.         curFrame=spritePtr&.currentFrameNum%+spritePtr&.frameAdvance%
  235.         LONG IF spritePtr&.frameAdvance%>0
  236.           IF curFrame>spritePtr&.lastFrameIndex%-1 THEN curFrame=spritePtr&.firstFrameIndex%
  237.         XELSE
  238.           IF curFrame<spritePtr&.firstFrameIndex% THEN curFrame=spritePtr&.lastFrameIndex%-1
  239.         END IF
  240.         'is there a frame change callback?
  241.         frameChangeProcPtr&=spritePtr&.frameChangeProcPtr&
  242.         'if so, call it…
  243.         IF frameChangeProcPtr&<>_nil THEN CALL frameChangeProcPtr&(spritePtr&,curFrame)
  244.         spritePtr&.currentFrameNum%=curFrame
  245.         'update frame time task
  246.         LONG IF spritePtr&.frameTimeInterval%>0
  247.           spritePtr&.frameTTHasFired%=_false
  248.           FN PrimeTime(spritePtr&+_frameTimeTask&,spritePtr&.frameTimeInterval%)
  249.         END IF
  250.         'set draw & erase flags
  251.         LONG IF spritePtr&.isVisible%
  252.           spritePtr&.needsToBeDrawn%=_zTrue
  253.           spritePtr&.needsToBeErased%=_zTrue
  254.         END IF
  255.       END IF
  256.       'move sprite....
  257.       LONG IF spritePtr&.moveTTHasFired%
  258.         'call moveProc
  259.         moveProcPtr&=spritePtr&.moveProcPtr&
  260.         CALL moveProcPtr&(SWPtr&,spritePtr&,spritePtr&+_currentRect)
  261.         'move currentRect(faster than OffsetRect!)
  262.         spritePtr&.currentRect.top%=spritePtr&.currentRect.top%+spritePtr&.yDelta%
  263.         spritePtr&.currentRect.left%=spritePtr&.currentRect.left%+spritePtr&.xDelta%
  264.         spritePtr&.currentRect.bottom%=spritePtr&.currentRect.bottom%+spritePtr&.yDelta%
  265.         spritePtr&.currentRect.right%=spritePtr&.currentRect.right%+spritePtr&.xDelta%
  266.         'update move time task
  267.         LONG IF spritePtr&.moveTimeInterval%>0
  268.           spritePtr&.moveTTHasFired%=_false
  269.           FN PrimeTime(spritePtr&+_moveTimeTask&,spritePtr&.moveTimeInterval%)
  270.         END IF
  271.         'set draw & erase flags
  272.         LONG IF spritePtr&.isVisible%
  273.           spritePtr&.needsToBeDrawn%=_zTrue
  274.           spritePtr&.needsToBeErased%=_zTrue
  275.         END IF
  276.       END IF
  277.     NEXT
  278.   NEXT
  279.   
  280. END FN
  281.  
  282. '---------------------------------------------------------------------
  283. 'SWAnimateSpriteWorld
  284. '---------------------------------------------------------------------
  285.  
  286. CLEAR LOCAL
  287. LOCAL FN SWAnimateSpriteWorld(SWPtr&)
  288.   'Draws sprites onto loadFrame and copies appropriate portions of
  289.   'loadFrame to screen.
  290.   
  291.   DIM tempRect.8
  292.   
  293.   savePort&=FN GetCurrPort
  294.   FN SetThePort(SWPtr&.loadFramePtr&)
  295.   
  296.   'erase sprites
  297.   FOR layer=0 TO SWPtr&.totalLayers%-1
  298.     layerPtr&=[SWPtr&+_layerList+(layer*4)]
  299.     FOR sprite=0 TO layerPtr&.totalSprites%-1
  300.       spritePtr&=[layerPtr&+_spriteList+(sprite*4)]
  301.       LONG IF spritePtr&.needsToBeErased%
  302.         'erase sprite by copying piece of backFrame to loadFrame
  303.         FN CopyOffScreenBits(SWPtr&.backFramePtr&,SWPtr&.loadFramePtr&,spritePtr&+_oldRect,spritePtr&+_oldRect,_srcCopy,_nil)
  304.         'check to see if we erased any non-moving sprites…
  305.         FOR tgtLayer=0 TO SWPtr&.totalLayers%-1
  306.           tgtLayerPtr&=[SWPtr&+_layerList+(tgtLayer*4)]
  307.           FOR tgtSprite=0 TO tgtLayerPtr&.totalSprites%-1
  308.             tgtSpritePtr&=[tgtLayerPtr&+_spriteList+(tgtSprite*4)]
  309.             LONG IF tgtSpritePtr&.needsToBeDrawn%=_false AND tgtSpritePtr&.isVisible%
  310.               LONG IF FN SECTRECT(#spritePtr&+_oldRect,#tgtSpritePtr&+_currentRect,tempRect)
  311.                 '…if so, make sure we redraw them
  312.                 tgtSpritePtr&.drawPartial%=_zTrue
  313.                 'get union of deltaRect and tempRect (faster than UnionRect!)
  314.                 IF tgtSpritePtr&.deltaRect.top%>tempRect.top% THEN tgtSpritePtr&.deltaRect.top%=tempRect.top%
  315.                 IF tgtSpritePtr&.deltaRect.left%>tempRect.left% THEN tgtSpritePtr&.deltaRect.left%=tempRect.left%
  316.                 IF tgtSpritePtr&.deltaRect.bottom%<tempRect.bottom% THEN tgtSpritePtr&.deltaRect.bottom%=tempRect.bottom%
  317.                 IF tgtSpritePtr&.deltaRect.right%<tempRect.right% THEN tgtSpritePtr&.deltaRect.right%=tempRect.right%
  318.               END IF
  319.             END IF
  320.           NEXT
  321.         NEXT
  322.       END IF
  323.     NEXT
  324.   NEXT
  325.   
  326.   'draw sprites in their new positions
  327.   FOR layer=0 TO SWPtr&.totalLayers%-1
  328.     layerPtr&=[SWPtr&+_layerList+(layer*4)]
  329.     FOR sprite=0 TO layerPtr&.totalSprites%-1
  330.       spritePtr&=[layerPtr&+_spriteList+(sprite*4)]
  331.       LONG IF spritePtr&.needsToBeDrawn% OR spritePtr&.drawPartial%
  332.         LONG IF spritePtr&.drawPartial%
  333.           CALL RECTRGN(spritePtr&.maskRegionHdl&,spritePtr&.deltaRect&)
  334.           maskRgnHdl&=spritePtr&.maskRegionHdl&
  335.           spritePtr&.drawPartial%=_false
  336.           'clear deltaRect
  337.           CALL SETRECT(spritePtr&.deltaRect&,0,0,0,0)
  338.         XELSE
  339.           maskRgnHdl&=_nil
  340.         END IF
  341.         framePtr&=[spritePtr&+_frameList+({spritePtr&+_currentFrameNum}*4)]
  342.         'draw mask frame
  343.         FN CopyOffScreenBits(framePtr&.maskMapPtr&,SWPtr&.loadFramePtr&,framePtr&+_fBoundsRect,spritePtr&+_currentRect,_srcBic,maskRgnHdl&)
  344.         'draw image frame
  345.         FN CopyOffScreenBits(framePtr&.imageMapPtr&,SWPtr&.loadFramePtr&,framePtr&+_fBoundsRect,spritePtr&+_currentRect,_srcOr,maskRgnHdl&)
  346.       END IF
  347.     NEXT
  348.   NEXT
  349.   
  350.   FN SetThePort(SWPtr&.windowFramePtr&)
  351.   
  352.   'copy loadFrame to screen
  353.   FOR layer=0 TO SWPtr&.totalLayers%-1
  354.     layerPtr&=[SWPtr&+_layerList+(layer*4)]
  355.     FOR sprite=0 TO layerPtr&.totalSprites%-1
  356.       spritePtr&=[layerPtr&+_spriteList+(sprite*4)]
  357.       LONG IF spritePtr&.needsToBeDrawn% OR spritePtr&.needsToBeErased%
  358.         'get union of oldRect and newRect (faster than UnionRect!)
  359.         IF spritePtr&.currentRect.top%>spritePtr&.oldRect.top% THEN spritePtr&.deltaRect.top%=spritePtr&.oldRect.top% ELSE spritePtr&.deltaRect.top%=spritePtr&.currentRect.top%
  360.         IF spritePtr&.currentRect.left%>spritePtr&.oldRect.left% THEN spritePtr&.deltaRect.left%=spritePtr&.oldRect.left% ELSE spritePtr&.deltaRect.left%=spritePtr&.currentRect.left%
  361.         IF spritePtr&.currentRect.bottom%<spritePtr&.oldRect.bottom% THEN spritePtr&.deltaRect.bottom%=spritePtr&.oldRect.bottom% ELSE spritePtr&.deltaRect.bottom%=spritePtr&.currentRect.bottom%
  362.         IF spritePtr&.currentRect.right%<spritePtr&.oldRect.right% THEN spritePtr&.deltaRect.right%=spritePtr&.oldRect.right% ELSE spritePtr&.deltaRect.right%=spritePtr&.currentRect.right%
  363.         'set mask region equal to deltaRect
  364.         CALL RECTRGN(spritePtr&.maskRegionHdl&,#spritePtr&+_deltaRect)
  365.         FN CopyOffScreenBits(SWPtr&.loadFramePtr&,SWPtr&.windowFramePtr&,spritePtr&+_deltaRect,spritePtr&+_deltaRect,_srcCopy,spritePtr&.maskRegionHdl&)
  366.         'clear draw & erase flags
  367.         spritePtr&.needsToBeDrawn%=_false
  368.         spritePtr&.needsToBeErased%=_false
  369.       END IF
  370.       'set old rect
  371.       BLOCKMOVE spritePtr&+_currentRect,spritePtr&+_oldRect,8
  372.     NEXT
  373.   NEXT
  374.   
  375.   FN SetThePort(savePort&)
  376. END FN
  377.  
  378. '---------------------------------------------------------------------
  379. 'SWAddLayerToWorld
  380. '---------------------------------------------------------------------
  381.  
  382. CLEAR LOCAL
  383. LOCAL FN SWAddLayerToWorld(SWPtr&,layerPtr&)
  384.   'Adds layerPtr& to specified SpriteWorld.
  385.   
  386.   LONG IF SWPtr&.totalLayers%<_maxLayers
  387.     offset=SWPtr&.totalLayers%*4
  388.     POKE LONG SWPtr&+_layerList+offset,layerPtr&
  389.     INC(SWPtr&.totalLayers%)
  390.   XELSE
  391.     err=_swTooManyLayers
  392.   END IF
  393. END FN=err
  394.  
  395. '---------------------------------------------------------------------
  396. 'SWFrameFromPict
  397. '---------------------------------------------------------------------
  398.  
  399. CLEAR LOCAL
  400. LOCAL FN SWFrameFromPict(framePtr&,pictID)
  401.   'Creates image and mask frames from specified PICT resource.
  402.   
  403.   DIM frameRect.8
  404.   maskID=pictID+2
  405.   
  406.   savePort&=FN GetCurrPort
  407.   
  408.   LONG IF gColorDepth<>32                         'no 32-bit QuickDraw?
  409.     INC(pictID)                                   '...then get B/W pict
  410.   END IF
  411.   
  412.   'create imageFrame...
  413.   pict&=FN GETPICTURE(pictID)
  414.   err=FN RESERROR
  415.   
  416.   LONG IF err=_noErr
  417.     frameRect;8=[pict&]+_picFrame
  418.     'make sure we're at 0,0
  419.     CALL OFFSETRECT(frameRect,-frameRect.left%,-frameRect.top%)
  420.     'copy frameRect to FramePtr.fBoundsRect
  421.     BLOCKMOVE @frameRect,framePtr&+_fBoundsRect,8
  422.     'create off screen port for image
  423.     offPort&=FN SWGetBestPort&(@frameRect)
  424.     LONG IF offPort&
  425.       framePtr&.imageMapPtr&=offPort&
  426.       FN SetThePort(offPort&)
  427.       CALL DRAWPICTURE(pict&,frameRect)           'draw picture to imageFrame
  428.       KILL PICTURE pict&
  429.     XELSE
  430.       err=_swOutOfMemory
  431.     END IF
  432.     
  433.     'create maskFrame...
  434.     pict&=FN GETPICTURE(maskID)
  435.     err=FN RESERROR
  436.     
  437.     LONG IF err=_noErr
  438.       'create off screen port for mask
  439.       offPort&=FN SWGetBestPort&(@frameRect)
  440.       LONG IF offPort&
  441.         framePtr&.maskMapPtr&=offPort&
  442.         FN SetThePort(offPort&)
  443.         CALL DRAWPICTURE(pict&,frameRect)         'draw picture to imageFrame
  444.         KILL PICTURE pict&
  445.       XELSE
  446.         err=_swOutOfMemory
  447.       END IF
  448.     END IF
  449.   END IF
  450.   
  451.   FN SetThePort(savePort&)
  452. END FN=err
  453.  
  454. '---------------------------------------------------------------------
  455. 'SWAddFrameToSprite
  456. '---------------------------------------------------------------------
  457.  
  458. CLEAR LOCAL
  459. LOCAL FN SWAddFrameToSprite(spritePtr&,framePtr&)
  460.   'Adds framePtr& to specified sprite.
  461.   
  462.   LONG IF spritePtr&.totalFrames%<_maxFrames
  463.     offset=spritePtr&.totalFrames%*4
  464.     POKE LONG spritePtr&+_frameList+offset,framePtr&
  465.     INC(spritePtr&.totalframes%)
  466.     spritePtr&.lastFrameIndex%=spritePtr&.totalFrames%
  467.   XELSE
  468.     err=_swTooManyFrames
  469.   END IF
  470. END FN=err
  471.  
  472. '---------------------------------------------------------------------
  473. 'SWInitSprite
  474. '---------------------------------------------------------------------
  475.  
  476. CLEAR LOCAL
  477. LOCAL FN SWInitSprite(spritePtr&,curFrame,curRectP&,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&)
  478.   'Given a pointer to a previously dimmed Sprite, sets initial values
  479.   'of a Sprite.
  480.   
  481.   spritePtr&.currentFrameNum%=curFrame
  482.   BLOCKMOVE curRectP&,spritePtr&+_currentRect,8
  483.   BLOCKMOVE curRectP&,spritePtr&+_oldRect,8
  484.   BLOCKMOVE boundsRectP&,spritePtr&+_sBoundsRect,8
  485.   spritePtr&.isVisible%=vis
  486.   spritePtr&.needsToBeErased%=_false
  487.   spritePtr&.needsToBeDrawn%=_zTrue
  488.   spritePtr&.drawPartial%=_false
  489.   spritePtr&.totalFrames%=0
  490.   spritePtr&.firstFrameIndex%=0
  491.   spritePtr&.lastFrameIndex%=0
  492.   spritePtr&.xDelta%=xDelta
  493.   spritePtr&.yDelta%=yDelta
  494.   spritePtr&.maskRegionHdl&=FN NEWRGN
  495.   spritePtr&.frameAdvance%=frameAdvance
  496.   spritePtr&.frameTimeTask.qLink&=_nil
  497.   spritePtr&.frameTimeTask.qType%=0
  498.   spritePtr&.frameTimeTask.tmAddr&=ttPtr&
  499.   spritePtr&.frameTimeTask.tmCount&=0
  500.   spritePtr&.frameTimeTask.tmWakeUp&=0
  501.   spritePtr&.frameTimeTask.tmReserved&=0
  502.   spritePtr&.frameTTHasFired%=_zTrue
  503.   spritePtr&.frameTimeInterval%=0
  504.   spritePtr&.frameChangeProcPtr&=_nil
  505.   spritePtr&.moveTimeTask.qLink&=_nil
  506.   spritePtr&.moveTimeTask.qType%=0
  507.   spritePtr&.moveTimeTask.tmAddr&=ttPtr&
  508.   spritePtr&.moveTimeTask.tmCount&=0
  509.   spritePtr&.moveTimeTask.tmWakeUp&=0
  510.   spritePtr&.moveTimeTask.tmReserved&=0
  511.   spritePtr&.moveTTHasFired%=_zTrue
  512.   spritePtr&.moveTimeInterval%=0
  513.   spritePtr&.moveProcPtr&=movePtr&
  514.   spritePtr&.collideProcPtr&=_nil
  515.   spritePtr&.isClone%=_false
  516.   'install time tasks
  517.   FN InsXTime(spritePtr&.frameTimeTask&)
  518.   FN InsXTime(spritePtr&.moveTimeTask&)
  519. END FN
  520.  
  521. '---------------------------------------------------------------------
  522. 'SWCloneSprite
  523. '---------------------------------------------------------------------
  524.  
  525. CLEAR LOCAL
  526. LOCAL FN SWCloneSprite(srcSpritePtr&,cloneSpritePtr&,ttPtr&)
  527.   'A cloned sprite is an exact duplicate of its source.  If you have
  528.   'assigned frames to the source sprite, the framelist of the clone
  529.   'will contain pointers to those same frames.  Thus, cloned sprites
  530.   'can share the same frames with their sources, which saves memory
  531.   'and processing time.  The isClone field is set TRUE for cloned
  532.   'sprites, so we can determine whether to remove frames from memory
  533.   'when disposing of a sprite (generally, you will only remove frames
  534.   'when disposing of a non-cloned sprite).
  535.   
  536.   'copy srcSprite data to cloneSprite
  537.   BLOCKMOVE srcSpritePtr&,cloneSpritePtr&,_SWSpriteRec
  538.   'frame time tasks are unique to each sprite…
  539.   cloneSpritePtr&.frameTimeTask.qLink&=_nil
  540.   cloneSpritePtr&.frameTimeTask.qType%=0
  541.   cloneSpritePtr&.frameTimeTask.tmAddr&=ttPtr&
  542.   cloneSpritePtr&.frameTimeTask.tmCount&=0
  543.   cloneSpritePtr&.frameTimeTask.tmWakeUp&=0
  544.   cloneSpritePtr&.frameTimeTask.tmReserved&=0
  545.   cloneSpritePtr&.frameTTHasFired%=_zTrue
  546.   cloneSpritePtr&.frameTimeInterval%=0
  547.   'so are mask regions…
  548.   spritePtr&.maskRegionHdl&=FN NEWRGN
  549.   'and so are move time tasks…
  550.   cloneSpritePtr&.moveTimeTask.qLink&=_nil
  551.   cloneSpritePtr&.moveTimeTask.qType%=0
  552.   cloneSpritePtr&.moveTimeTask.tmAddr&=ttPtr&
  553.   cloneSpritePtr&.moveTimeTask.tmCount&=0
  554.   cloneSpritePtr&.moveTimeTask.tmWakeUp&=0
  555.   cloneSpritePtr&.moveTimeTask.tmReserved&=0
  556.   cloneSpritePtr&.moveTTHasFired%=_zTrue
  557.   cloneSpritePtr&.moveTimeInterval%=0
  558.   'mark sprite as cloned
  559.   cloneSpritePtr&.isClone%=_zTrue
  560.   'install time tasks
  561.   FN InsXTime(cloneSpritePtr&.frameTimeTask&)
  562.   FN InsXTime(cloneSpritePtr&.moveTimeTask&)
  563. END FN
  564.  
  565. '---------------------------------------------------------------------
  566. 'SWSpriteFromPict
  567. '---------------------------------------------------------------------
  568.  
  569. CLEAR LOCAL
  570. DIM frameRect.8
  571. LOCAL FN SWSpriteFromPict(spritePtr&,curFrame,curX,curY,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&,pictID)
  572.   'Inits a Sprite based on pictID (that is, its curRect field is based
  573.   'on the size of pictID, offset to curX,curY.  Returns resErr.
  574.   
  575.   pict&=FN GETPICTURE(pictID)
  576.   resErr=FN RESERROR
  577.   
  578.   LONG IF resErr=_noErr
  579.     frameRect;8=[pict&]+_picFrame
  580.     'pin rect to curX,curY…
  581.     CALL OFFSETRECT(frameRect,curX-frameRect.left%,curY-frameRect.top%)
  582.     FN SWInitSprite(spritePtr&,curFrame,@frameRect,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&)
  583.   END IF
  584. END FN=resErr
  585.  
  586. '---------------------------------------------------------------------
  587. 'SWAddSpriteToLayer
  588. '---------------------------------------------------------------------
  589.  
  590. CLEAR LOCAL
  591. LOCAL FN SWAddSpriteToLayer(layerPtr&,spritePtr&)
  592.   'Adds spritePtr& to the specified layer.
  593.   
  594.   LONG IF layerPtr&.totalSprites%<_maxSprites
  595.     offset=layerPtr&.totalSprites%*4
  596.     POKE LONG layerPtr&+_spriteList+offset,spritePtr&
  597.     INC(layerPtr&.totalSprites%)
  598.   XELSE
  599.     err=_swTooManySprites
  600.   END IF
  601. END FN=err
  602.  
  603. '---------------------------------------------------------------------
  604. 'SWSetSpriteMoveProc
  605. '---------------------------------------------------------------------
  606.  
  607. CLEAR LOCAL
  608. LOCAL FN SWSetSpriteMoveProc(spritePtr&,moveProcPtr&)
  609.   'Sets the movement procedure for a sprite.
  610.   
  611.   spritePtr&.moveProcPtr&=moveProcPtr&
  612. END FN
  613.  
  614. '---------------------------------------------------------------------
  615. 'SWSetCollideProc
  616. '---------------------------------------------------------------------
  617.  
  618. CLEAR LOCAL
  619. LOCAL FN SWSetCollideProc(spritePtr&,collideProcPtr&)
  620.   'Set the collide procedure for a sprite.
  621.   
  622.   spritePtr&.collideProcPtr&=collideProcPtr&
  623. END FN
  624.  
  625. '---------------------------------------------------------------------
  626. 'SWSetFrameChangeProc
  627. '---------------------------------------------------------------------
  628.  
  629. CLEAR LOCAL
  630. LOCAL FN SWSetFrameChangeProc(spritePtr&,frameChangeProcPtr&)
  631.   'Sets the frame change procedure for a sprite.
  632.   
  633.   spritePtr&.frameChangeProcPtr&=frameChangeProcPtr&
  634. END FN
  635.  
  636. '---------------------------------------------------------------------
  637. 'SWSetMoveDelta
  638. '---------------------------------------------------------------------
  639.  
  640. CLEAR LOCAL
  641. LOCAL FN SWSetMoveDelta(spritePtr&,xDelta,yDelta)
  642.   'Sets the number of pixels a sprite should be moved by SWProcessSpriteWorld
  643.   'horizontally and vertically.
  644.   
  645.   spritePtr&.xDelta%=xDelta
  646.   spritePtr&.yDelta%=yDelta
  647. END FN
  648.  
  649. '---------------------------------------------------------------------
  650. 'SWOffsetSprite
  651. '---------------------------------------------------------------------
  652.  
  653. CLEAR LOCAL
  654. LOCAL FN SWOffsetSprite(spritePtr&,xDelta,yDelta)
  655.   'Moves sprite to a relative position on the screen.
  656.   
  657.   spritePtr&.currentRect.top%=spritePtr&.currentRect.top%+yDelta
  658.   spritePtr&.currentRect.left%=spritePtr&.currentRect.left%+xDelta
  659.   spritePtr&.currentRect.bottom%=spritePtr&.currentRect.bottom%+yDelta
  660.   spritePtr&.currentRect.right%=spritePtr&.currentRect.right%+yDelta
  661.   LONG IF spritePtr&.isVisible%
  662.     spritePtr&.needsToBeErased%=_zTrue
  663.     spritePtr&.needsToBeDrawn%=_zTrue
  664.   END IF
  665. END FN
  666.  
  667. '---------------------------------------------------------------------
  668. 'SWSetSpriteFrameAdv
  669. '---------------------------------------------------------------------
  670.  
  671. CLEAR LOCAL
  672. LOCAL FN SWSetSpriteFrameAdv(spritePtr&,frameAdv)
  673.   'Sets the number by which SWProcessSpriteWorld will advance the current
  674.   'frame.
  675.   
  676.   spritePtr&.frameAdvance%=frameAdv
  677. END FN
  678.  
  679. '---------------------------------------------------------------------
  680. 'SWSetCurrentFrame
  681. '---------------------------------------------------------------------
  682.  
  683. CLEAR LOCAL
  684. LOCAL FN SWSetCurrentFrame(spritePtr&,frameNum)
  685.   'Sets the sprite's current frame.
  686.   
  687.   spritePtr&.currentFrameNum%=frameNum
  688. END FN
  689.  
  690. '---------------------------------------------------------------------
  691. 'SWSetSpriteVisible
  692. '---------------------------------------------------------------------
  693.  
  694. CLEAR LOCAL
  695. LOCAL FN SWSetSpriteVisible(spritePtr&,vis)
  696.   'Causes a sprite to appear or disappear.
  697.   
  698.   spritePtr&.isVisible%=vis
  699.   spritePtr&.needsToBeDrawn%=vis
  700.   spritePtr&.needsToBeErased%=NOT(vis)
  701. END FN
  702.  
  703. '---------------------------------------------------------------------
  704. 'SWGetCurRect
  705. '---------------------------------------------------------------------
  706.  
  707. CLEAR LOCAL
  708. DIM rect.8
  709. LOCAL FN SWGetCurRect(spritePtr&,rect;8)
  710.   'Returns sprite's currentRect.
  711.   
  712.   BLOCKMOVE spritePtr&+_currentRect,@rect,8
  713. END FN
  714.  
  715. '---------------------------------------------------------------------
  716. 'SWSetCurRect
  717. '---------------------------------------------------------------------
  718.  
  719. CLEAR LOCAL
  720. DIM rect.8
  721. LOCAL FN SWSetCurRect(spritePtr&,rect;8)
  722.   'Sets current and old rect of sprite.
  723.   
  724.   BLOCKMOVE @rect,spritePtr&+_currentRect,8
  725.   BLOCKMOVE @rect,spritePtr&+_oldRect,8
  726. END FN
  727.  
  728. '---------------------------------------------------------------------
  729. 'SWSetSpriteLocation
  730. '---------------------------------------------------------------------
  731.  
  732. CLEAR LOCAL
  733. LOCAL FN SWSetSpriteLocation(spritePtr&,x,y)
  734.   'Sets current and old location of sprite, based on x,y coordinates.
  735.   
  736.   CALL OFFSETRECT(#spritePtr&+_currentRect,x-spritePtr&.currentRect.left%,y-spritePtr&.currentRect.top%)
  737.   BLOCKMOVE spritePtr&+_currentRect,spritePtr&+_oldRect,8
  738. END FN
  739.  
  740. '---------------------------------------------------------------------
  741. 'SWMoveSpriteRect
  742. '---------------------------------------------------------------------
  743.  
  744. CLEAR LOCAL
  745. DIM rect.8
  746. LOCAL FN SWMoveSpriteRect(spritePtr&,rect;8)
  747.   'Moves sprite to new rectangle.
  748.   
  749.   BLOCKMOVE @rect,spritePtr&+_currentRect,8
  750.   LONG IF spritePtr&.isVisible%
  751.     spritePtr&.needsToBeErased%=_zTrue
  752.     spritePtr&.needsToBeDrawn%=_zTrue
  753.   END IF
  754. END FN
  755.  
  756. '---------------------------------------------------------------------
  757. 'SWMoveSprite
  758. '---------------------------------------------------------------------
  759.  
  760. CLEAR LOCAL
  761. LOCAL FN SWMoveSprite(spritePtr&,x,y)
  762.   'Moves sprite to new x,y coordinates.
  763.   
  764.   CALL OFFSETRECT(#spritePtr&+_currentRect,x-spritePtr&.currentRect.left%,y-spritePtr&.currentRect.top%)
  765.   LONG IF spritePtr&.isVisible%
  766.     spritePtr&.needsToBeErased%=_zTrue
  767.     spritePtr&.needsToBeDrawn%=_zTrue
  768.   END IF
  769. END FN
  770.  
  771. '---------------------------------------------------------------------
  772. 'SWSetMoveBounds
  773. '---------------------------------------------------------------------
  774.  
  775. CLEAR LOCAL
  776. DIM rect.8
  777. LOCAL FN SWSetMoveBounds(spritePtr&,rect;8)
  778.   'Sets the bounding rectangle of the specified sprite.
  779.   BLOCKMOVE @rect,spritePtr&+_sBoundsRect,8
  780. END FN
  781.  
  782. '---------------------------------------------------------------------
  783. 'SWSetFrameRange
  784. '---------------------------------------------------------------------
  785.  
  786. CLEAR LOCAL
  787. LOCAL FN SWSetFrameRange(spritePtr&,firstFrame,lastFrame)
  788.   'Sets the range of frame indexes to be interated in SWProcessSpriteWorld.
  789.   
  790.   spritePtr&.firstFrameIndex%=firstFrame
  791.   spritePtr&.lastFrameIndex%=lastFrame
  792. END FN
  793.  
  794. '---------------------------------------------------------------------
  795. 'SWIsSpriteInRect
  796. '---------------------------------------------------------------------
  797.  
  798. CLEAR LOCAL
  799. DIM rect.8
  800. LOCAL FN SWIsSpriteInRect(spritePtr&,rect;8)
  801.   'Returns _zTrue (-1) if sprite's current rect is equal to or
  802.   'contained in rect.
  803. END FN=(spritePtr&.currentRect.top%>=rect.top% AND spritePtr&.currentRect.left%>=rect.left% AND spritePtr&.currentRect.bottom%<=rect.bottom% AND spritePtr&.currentRect.right%<=rect.right%)
  804.  
  805. '---------------------------------------------------------------------
  806. 'SWSpriteSectRect
  807. '---------------------------------------------------------------------
  808.  
  809. CLEAR LOCAL
  810. DIM rect.8
  811. LOCAL FN SWSpriteSectRect(spritePtr&,rect;8,sectRectPtr&)
  812.   'Returns _zTrue (-1) if the sprite's current rect intersects
  813.   'rect.  If there is an intersection, sectRect will contain the
  814.   'intersecting rectangle.
  815. END FN=-(FN SECTRECT(#spritePtr&+_currentRect,rect,#sectRectPtr&))
  816.  
  817. '---------------------------------------------------------------------
  818. 'SWRemoveLayer
  819. '---------------------------------------------------------------------
  820.  
  821. CLEAR LOCAL
  822. LOCAL FN SWRemoveLayer(SWPtr&,layerPtr&)
  823.   'Removes a layer from the specified SpriteWorld.
  824.   
  825.   'find layer in layerlist
  826.   FOR x=0 TO SWPtr&.totalLayers%-1
  827.     targetLayer&=[SWPtr&+_layerList+(x*4)]
  828.     LONG IF layerPtr&=targetLayer&
  829.       'delete layer and adjust layerList
  830.       FOR layer=x TO SWPtr&.totalLayers%-2
  831.         &SWPtr&+_layerList+(layer*4),[SWPtr&+_layerList+((layer+1)*4)]
  832.       NEXT
  833.       &SWPtr&+_layerList+((SWPtr&.totalLayers%-1)*4),_nil
  834.       DEC(SWPtr&.totalLayers%)
  835.       EXIT FOR
  836.     END IF
  837.   NEXT
  838. END FN
  839.  
  840. '---------------------------------------------------------------------
  841. 'SWRemoveSprite
  842. '---------------------------------------------------------------------
  843.  
  844. CLEAR LOCAL
  845. LOCAL FN SWRemoveSprite(layerPtr&,spritePtr&)
  846.   'Removes a sprite from the specified layer.  Does not dispose of the
  847.   'sprite.
  848.   
  849.   'find sprite in spritelist
  850.   FOR x=0 TO layerPtr&.totalSprites%-1
  851.     targetSprite&=[layerPtr&+_spriteList+(x*4)]
  852.     LONG IF spritePtr&=targetSprite&
  853.       'delete sprite and adjust spriteList
  854.       FOR sprite=x TO layerPtr&.totalSprites%-2
  855.         &layerPtr&+_spriteList+(sprite*4),[layerPtr&+_spriteList+((sprite+1)*4)]
  856.       NEXT
  857.       &layerPtr&+_spriteList+((layerPtr&.totalSprites%-1)*4),_nil
  858.       DEC(layerPtr&.totalSprites%)
  859.       EXIT FOR
  860.     END IF
  861.   NEXT
  862. END FN
  863.  
  864. '---------------------------------------------------------------------
  865. 'SWRemoveFrame
  866. '---------------------------------------------------------------------
  867.  
  868. CLEAR LOCAL
  869. LOCAL FN SWRemoveFrame(spritePtr&,framePtr&)
  870.   'Removes a frame from the specified sprite. Does not dispose of the
  871.   'frame.
  872.   
  873.   'find frame in framelist
  874.   FOR x=0 TO spritePtr&.totalFrames%-1
  875.     targetFrame&=[spritePtr&+_frameList+(x*4)]
  876.     LONG IF framePtr&=targetFrame&
  877.       'delete frame and adjust frameList
  878.       FOR frame=x TO spritePtr&.totalFrames%-2
  879.         &spritePtr&+_frameList+(frame*4),[spritePtr&+_frameList+((frame+1)*4)]
  880.       NEXT
  881.       &spritePtr&+_frameList+((spritePtr&.totalFrames%-1)*4),_nil
  882.       DEC(spritePtr&.totalFrames%)
  883.       'adjust lastFrameIndex, if necessary
  884.       IF spritePtr&.totalFrames%<spritePtr&.lastFrameIndex% THEN spritePtr&.lastFrameIndex%=spritePtr&.totalFrames%
  885.       EXIT FOR
  886.     END IF
  887.   NEXT
  888. END FN
  889.  
  890. '---------------------------------------------------------------------
  891. 'SWIsTaskPrimed
  892. '---------------------------------------------------------------------
  893.  
  894. CLEAR LOCAL
  895. LOCAL FN SWIsTaskPrimed(tmTaskPtr&)
  896.   'Returns _zTrue if timeTask has been primed .
  897. END FN=((tmTaskPtr&.qType% AND &8000)<>0)
  898.  
  899. '---------------------------------------------------------------------
  900. 'SWSetFrameTime
  901. '---------------------------------------------------------------------
  902.  
  903. CLEAR LOCAL
  904. LOCAL FN SWSetFrameTime(spritePtr&,timeInterval)
  905.   'Sets the time in milliseconds between frame changes.
  906.   
  907.       spritePtr&.frameTimeInterval%=timeInterval
  908.       LONG IF timeInterval>0
  909.     'if task not primed…
  910.     LONG IF (NOT FN SWIsTaskPrimed(spritePtr&.frameTimeTask&))
  911.       '…prime it
  912.       spritePtr&.frameTTHasFired%=_zTrue
  913.     END IF
  914.       XELSE 
  915.     'is the time interval negative?
  916.     LONG IF timeInterval<0
  917.       'if the task is primed…
  918.       LONG IF FN SWIsTaskPrimed(spritePtr&.frameTimeTask&)
  919.         '…remove it
  920.         FN RmvTime(spritePtr&.frameTimeTask&)
  921.         FN InsXTime(spritePtr&.frameTimeTask&)
  922.       END IF
  923.       'the timeInterval is negative, which means never change the frame
  924.       spritePtr&.frameTTHasFired%=_false
  925.     XELSE
  926.       'time interval=0; this means change frames as quickly as possible
  927.       spritePtr&.frameTTHasFired%=_zTrue
  928.     END IF
  929.   END IF
  930. END FN
  931.  
  932. '---------------------------------------------------------------------
  933. 'SWSetMoveTime
  934. '---------------------------------------------------------------------
  935.  
  936. CLEAR LOCAL
  937. LOCAL FN SWSetMoveTime(spritePtr&,timeInterval)
  938.   'Sets the time in milliseconds between sprite moves.
  939.   
  940.       spritePtr&.moveTimeInterval%=timeInterval
  941.       LONG IF timeInterval>0
  942.     'if task not primed…
  943.     LONG IF (NOT FN SWIsTaskPrimed(spritePtr&.moveTimeTask&))
  944.       '…prime it
  945.       spritePtr&.moveTTHasFired%=_zTrue
  946.     END IF
  947.       XELSE 
  948.     'is the time interval negative?
  949.     LONG IF timeInterval<0
  950.       'if the task is primed…
  951.       LONG IF FN SWIsTaskPrimed(spritePtr&.moveTimeTask&)
  952.         '…remove it
  953.         FN RmvTime(spritePtr&.moveTimeTask&)
  954.         FN InsXTime(spritePtr&.moveTimeTask&)
  955.       END IF
  956.       'the timeInterval is negative, which means never move sprite
  957.       spritePtr&.moveTTHasFired%=_false
  958.     XELSE
  959.       'time interval=0; this means move sprite as quickly as possible
  960.       spritePtr&.moveTTHasFired%=_zTrue
  961.     END IF
  962.   END IF
  963. END FN
  964.  
  965. '---------------------------------------------------------------------
  966. 'SWUpdateSpriteWorld
  967. '---------------------------------------------------------------------
  968.  
  969. CLEAR LOCAL
  970. LOCAL FN SWUpdateSpriteWorld(SWPtr&)
  971.   'Copies entire loadframe to screen.  Used to refesh screen following
  972.   'an update event.
  973.   
  974.   FN CopyOffScreenBits(SWPtr&.loadFramePtr&,SWPtr&.windowFramePtr&,SWPtr&+_boundsRect,SWPtr&+_boundsRect,_srcCopy,_nil)
  975. END FN
  976.  
  977. '---------------------------------------------------------------------
  978. 'SWCollideSpriteLayer
  979. '---------------------------------------------------------------------
  980.  
  981. CLEAR LOCAL
  982. DIM srcRect.8,destRect.8,sectRect.8
  983. LOCAL FN SWCollideSpriteLayer(srcLayerPtr&,destLayerPtr&)
  984.   'Detects collisions between sprites in srcLayer and sprites in
  985.   'destLayer.  If collision is detected, calls collideProc of srcSprite.
  986.   'To detect collisions between sprites in the same layer, pass the
  987.   'same layer variable in both srcLayerPtr& and destLayerPtr&.
  988.   
  989.   FOR srcSprite=0 TO srcLayerPtr&.totalSprites%-1
  990.     srcSpritePtr&=[srcLayerPtr&+_spriteList+(srcSprite*4)]
  991.     FOR destSprite=0 TO destLayerPtr&.totalSprites%-1
  992.       destSpritePtr&=[destLayerPtr&+_spriteList+(destSprite*4)]
  993.       LONG IF srcSpritePtr&<>destSpritePtr&
  994.         LONG IF FN SECTRECT(#srcSpritePtr&+_currentRect,#destSpritePtr&+_currentRect,sectRect)
  995.           collideProcPtr&=srcSpritePtr&.collideProcPtr&
  996.           IF collideProcPtr&<>_nil THEN CALL collideProcPtr&(srcSpritePtr&,destSpritePtr&,@sectRect)
  997.         END IF
  998.       END IF
  999.     NEXT
  1000.   NEXT
  1001. END FN
  1002.  
  1003.